﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;

namespace FrontEnd.Storage
{
    ///-------------------------------------------------------------------------------------------------
    /// <summary> Used to save and load game list. </summary>
    ///-------------------------------------------------------------------------------------------------
    public class GameListStg : List<Game>
    {
        #region Xml Constants

        private const String ROOT_NODE = "GameList";
        private const String GAMES_NODE = "Games";
        private const String GAME_NODE = "Game";

        #endregion

        #region Constructor(s)

        ///-------------------------------------------------------------------------------------------------
        /// <summary> Default constructor. </summary>
        ///-------------------------------------------------------------------------------------------------
        public GameListStg()
            : base()
        {
            Clear();
        }

        ///-------------------------------------------------------------------------------------------------
        /// <summary> Copy constructor. </summary>
        /// <param name="gameList"> List of games. </param>
        ///-------------------------------------------------------------------------------------------------
        public GameListStg(GameListStg gameList)
            : base()
        {
            Copy(gameList);
        }

        ///-------------------------------------------------------------------------------------------------
        /// <summary> Constructor. </summary>
        /// <param name="filepath"> The filepath to load from. </param>
        ///-------------------------------------------------------------------------------------------------
        public GameListStg(String filepath)
            : base()
        {
            LoadFrom(filepath);
        }

        #endregion

        #region Public

        ///-------------------------------------------------------------------------------------------------
        /// <summary> Copies the given game list. </summary>
        /// <exception cref="ArgumentNullException"> Thrown when one or more required arguments are null. </exception>
        /// <param name="gameList"> List of games. </param>
        ///-------------------------------------------------------------------------------------------------
        public void Copy(GameListStg gameList)
        {
            if (gameList == null)
                throw new ArgumentNullException("gameList");

            Clear();
            foreach (Game game in gameList)
                Add(new Game(game));
        }

        ///-------------------------------------------------------------------------------------------------
        /// <summary> Loads file at specified location. </summary>
        /// <param name="filepath"> The file to load from. </param>
        ///-------------------------------------------------------------------------------------------------
        public virtual void LoadFrom(String filepath)
        {
            if (filepath == null)
                throw new ArgumentNullException("filepath");

            if (!File.Exists(filepath))
                throw new FileNotFoundException("Game list not found.", filepath);

            // Load file into xml document.
            XmlDocument document = new XmlDocument();
            using (StreamReader sr = new StreamReader(filepath))
                document.Load(sr);

            // Root.
            XmlNode rootNode = document.SelectSingleNode(ROOT_NODE);

            // Games.
            Clear();
            foreach (XmlNode gameNode in rootNode.SelectSingleNode(GAMES_NODE).SelectNodes(GAME_NODE))
                Add(new Game(gameNode));
        }

        ///-------------------------------------------------------------------------------------------------
        /// <summary> Saves to file at specified location. Any existing file will be overwritten. </summary>
        /// <param name="filepath"> The file to save to. </param>
        ///-------------------------------------------------------------------------------------------------
        public virtual void SaveTo(String filepath)
        {
            if (filepath == null)
                throw new ArgumentNullException("filepath");

            // Document and root.
            XmlDocument document = new XmlDocument();
            XmlNode rootNode = document.CreateElement(ROOT_NODE);
            document.AppendChild(rootNode);

            // Games parent.
            XmlNode gameParentNode = document.CreateElement(GAMES_NODE);
            rootNode.AppendChild(gameParentNode);

            // Games.
            foreach (Game game in this)
            {
                XmlNode gameNode = document.CreateElement(GAME_NODE);
                game.SaveTo(gameNode);
                gameParentNode.AppendChild(gameNode);
            }

            // Save file.
            using (StreamWriter sw = new StreamWriter(filepath, false, Encoding.UTF8))
                document.Save(sw);
        }

        #endregion
    }
}
